import numpy as np

class Target:
    def __init__(self, grid_size, target_id=0):
        self.id = target_id
        # 目标位置（可以是固定的或移动的）
        self.position = (grid_size // 2, grid_size // 2)  # 初始位置在网格中心
        self.grid_size = grid_size
        self.is_surrounded = False
        self.required_uavs = 3  # 需要多少架无人机才能完成合围
        self.surrounding_uavs = set()  # 当前合围的无人机ID集合
        self.escape_attempts = 0
        self.max_escape_attempts = 10
        
        # 目标移动相关
        self.is_mobile = True
        self.speed = 0.5  # 目标移动速度
        self.move_probability = 0.3  # 每步移动的概率
        
    def update_surrounding_status(self, uav_positions):
        """更新合围状态"""
        self.surrounding_uavs.clear()
        
        # 检查哪些无人机在合围范围内
        for uav_id, uav_pos in enumerate(uav_positions):
            distance = np.linalg.norm(np.array(self.position) - np.array(uav_pos))
            if distance <= 2.0:  # 合围距离阈值
                self.surrounding_uavs.add(uav_id)
        
        # 检查是否形成有效合围（需要无人机分布在目标周围）
        if len(self.surrounding_uavs) >= self.required_uavs:
            self.is_surrounded = self._check_encirclement(uav_positions)
        else:
            self.is_surrounded = False
            
    def _check_encirclement(self, uav_positions):
        """检查是否形成有效的合围"""
        if len(self.surrounding_uavs) < self.required_uavs:
            return False
            
        # 计算无人机相对于目标的角度分布
        angles = []
        for uav_id in self.surrounding_uavs:
            uav_pos = uav_positions[uav_id]
            dx = uav_pos[0] - self.position[0]
            dy = uav_pos[1] - self.position[1]
            angle = np.arctan2(dy, dx)
            angles.append(angle)
        
        # 检查角度分布是否足够均匀（简单检查：最大角度间隔不超过120度）
        angles.sort()
        max_gap = 0
        for i in range(len(angles)):
            gap = angles[(i + 1) % len(angles)] - angles[i]
            if gap < 0:
                gap += 2 * np.pi
            max_gap = max(max_gap, gap)
        
        return max_gap <= 2 * np.pi / 3  # 120度
    
    def attempt_escape(self):
        """目标尝试逃脱"""
        if self.is_surrounded and self.escape_attempts < self.max_escape_attempts:
            self.escape_attempts += 1
            # 逃脱成功概率随合围无人机数量减少
            escape_prob = max(0.1, 0.5 - 0.1 * len(self.surrounding_uavs))
            return np.random.random() < escape_prob
        return False
    
    def move(self):
        """目标移动逻辑"""
        if not self.is_mobile or np.random.random() > self.move_probability:
            return
            
        # 如果被合围，移动概率降低
        if self.is_surrounded:
            if np.random.random() > 0.1:  # 被合围时只有10%概率移动
                return
        
        # 随机移动
        dx = np.random.choice([-1, 0, 1]) * self.speed
        dy = np.random.choice([-1, 0, 1]) * self.speed
        
        new_x = max(0, min(self.grid_size - 1, self.position[0] + dx))
        new_y = max(0, min(self.grid_size - 1, self.position[1] + dy))
        
        self.position = (new_x, new_y)
    
    def get_state(self):
        """获取目标状态"""
        return {
            'position': self.position,
            'is_surrounded': self.is_surrounded,
            'surrounding_count': len(self.surrounding_uavs),
            'escape_attempts': self.escape_attempts
        }